package com.wingscode.util.retrofit;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

/**
 * Retrofit工具类
 *
 * @author CrazyHuskar
 * caeat at 2019-01-15  11:19
 */
public class MyUtilRetrofit {
    private MyApiServer myApiServer;
    private Retrofit retrofit;
    private static MyUtilRetrofit myUtilRetrofit;

    public static MyUtilRetrofit getInstance() {
        if (myUtilRetrofit == null) {
            myUtilRetrofit = new MyUtilRetrofit();
        }
        return myUtilRetrofit;
    }

    /**
     * 初始化URL
     *
     * @param baseUrl
     * @return
     */
    public MyUtilRetrofit init(String baseUrl) {
        retrofit = new Retrofit.Builder().baseUrl(baseUrl).build();
        myApiServer = retrofit.create(MyApiServer.class);
        return this;
    }

    /**
     * 获取Retrofit
     *
     * @return
     */
    public Retrofit getRetrofit() {
        return retrofit;
    }

    /**
     * 获取Retrofit
     *
     * @return
     */
    public MyApiServer getServer() {
        return myApiServer;
    }

    /**
     * get
     *
     * @param headers
     * @param url
     * @param myRetrofitCallback
     **/
    public void executeGet(Map<String, String> headers, String url, MyRetrofitCallback<String> myRetrofitCallback) {
        myApiServer.executeGet(headers, url).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    myRetrofitCallback.onSuccess(response.body().string());
                } catch (IOException e) {
                    myRetrofitCallback.onFailure(e.getMessage());
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable throwable) {
                myRetrofitCallback.onFailure(throwable.getMessage());
            }
        });
    }

    /**
     * post
     *
     * @param headers
     * @param url
     * @param params
     * @param myRetrofitCallback
     **/
    public void executePost(Map<String, String> headers, String url, Map<String, String> params, MyRetrofitCallback<String> myRetrofitCallback) {
        myApiServer.executePost(headers, url, params).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    myRetrofitCallback.onSuccess(response.body().string());
                } catch (IOException e) {
                    myRetrofitCallback.onFailure(e.getMessage());
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable throwable) {
                myRetrofitCallback.onFailure(throwable.getMessage());
            }
        });
    }

    /**
     * json
     *
     * @param headers
     * @param url
     * @param jsonString
     * @param myRetrofitCallback
     **/
    public void executeJson(Map<String, String> headers, String url, String jsonString, MyRetrofitCallback<String> myRetrofitCallback) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonString);
        myApiServer.executeJson(headers, url, requestBody).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    myRetrofitCallback.onSuccess(response.body().string());
                } catch (IOException e) {
                    myRetrofitCallback.onFailure(e.getMessage());
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable throwable) {
                myRetrofitCallback.onFailure(throwable.getMessage());
            }
        });
    }

    /**
     * 上传文件
     *
     * @param headers
     * @param url
     * @param files
     * @param params
     * @param myRetrofitCallback
     */
    public void uploadFiles(Map<String, String> headers, String url, List<File> files, Map<String, String> params, MyRetrofitCallback<String> myRetrofitCallback) {
        Map<String, RequestBody> requestBodyMap = new HashMap<>();
        for (int i = 0; i < files.size(); i++) {
            requestBodyMap.put("file" + "\";filename=\"" + files.get(i).getName(), RequestBody.create(MediaType.parse("multipart/form-data"), files.get(i)));
        }
        for (String key : params.keySet()) {
            requestBodyMap.put(key, RequestBody.create(MediaType.parse("text/plain"), params.get(key)));
        }
        uploadFiles(headers, url, requestBodyMap, myRetrofitCallback);
    }

    /**
     * 上传文件
     *
     * @param headers
     * @param url
     * @param files
     * @param jsonString
     * @param myRetrofitCallback
     */
    public void uploadFiles(Map<String, String> headers, String url, List<File> files, String jsonString, MyRetrofitCallback<String> myRetrofitCallback) {
        Map<String, RequestBody> requestBodyMap = new HashMap<>();
        for (int i = 0; i < files.size(); i++) {
            requestBodyMap.put("file" + "\";filename=\"" + files.get(i).getName(), RequestBody.create(MediaType.parse("multipart/form-data"), files.get(i)));
        }
        requestBodyMap.put("json", RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonString));
        uploadFiles(headers, url, requestBodyMap, myRetrofitCallback);
    }

    /**
     * 上传文件
     *
     * @param headers
     * @param url
     * @param requestBodyMap
     * @param myRetrofitCallback
     */
    public void uploadFiles(Map<String, String> headers, String url, Map<String, RequestBody> requestBodyMap, MyRetrofitCallback<String> myRetrofitCallback) {
        myApiServer.uploadFiles(headers, url, requestBodyMap).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    myRetrofitCallback.onSuccess(response.body().string());
                } catch (IOException e) {
                    myRetrofitCallback.onFailure(e.getMessage());
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable throwable) {
                myRetrofitCallback.onFailure(throwable.getMessage());
            }
        });
    }

    /**
     * 下载文件
     *
     * @param headers
     * @param fileUrl
     * @param myRetrofitCallback
     */
    public void downloadFile(Map<String, String> headers, String fileUrl, MyRetrofitCallback<ResponseBody> myRetrofitCallback) {
        myApiServer.downloadFile(headers, fileUrl).enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                myRetrofitCallback.onSuccess(response.body());
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable throwable) {
                myRetrofitCallback.onFailure(throwable.getMessage());
            }
        });
    }
}
